﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.Globalization;
using GTA.ExceptionHandling;

namespace GTA
{
    public class BaseForm : Form
    {
        #region Local Objects
        protected SortOrder sortOrder = SortOrder.Descending;
        protected Int32 columnOrder = Int32.MinValue;
        #endregion

        #region Properties
        public FrmMain MainForm
        {
            get { return GetMainForm(); }
        }
        #endregion

        #region Constants
        private const string BASE_WINDOW_TITLE = "GTA - ";
        protected const string DATE_FORMAT = "dd/MM/yyyy";
        protected const string DATE_FORMAT_FULL = "dd/MM/yyyy - HH:mm:ss";
        #endregion

        #region Starting Form
        public BaseForm()
        {
            this.Load += new EventHandler(BaseForm_Load);
            this.KeyDown += new KeyEventHandler(BaseForm_KeyDown);
            this.Icon = GTA.Properties.Resources.Scheduled_Tasks;
        }
        void BaseForm_KeyDown(object sender, KeyEventArgs e)
        {
            if (!(this is FrmMain))
            {
                if (e.KeyCode == Keys.Escape)
                    this.Close();
            }
        }
        void BaseForm_Load(object sender, EventArgs e)
        {
            this.Text = BASE_WINDOW_TITLE + this.Text;
            SetControlKeyDownEvent(this.Controls);
        }
        private void SetControlKeyDownEvent(Control.ControlCollection controlCollection)
        {
            foreach (Control ctrl in controlCollection)
            {
                ctrl.KeyDown += new KeyEventHandler(BaseForm_KeyDown);
                if (ctrl.Controls.Count > 0)
                    SetControlKeyDownEvent(ctrl.Controls);
            }
        }
        #endregion

        #region Methods
        protected void HandleException(String operation, Exception ex)
        {
            CustomMessageBox.CustomMessageBox.ShowError(operation, this, ex);
        }
        protected void SortList(ListView lista, OrdenacaoListView.Tipo tipoColuna, ref Int32 columOrder, ref SortOrder sentidoOrder, Int32 column)
        {
            try
            {
                if (columOrder == Int32.MinValue)
                    columOrder = column;

                if (columOrder == column)
                {
                    if (sentidoOrder == SortOrder.Ascending)
                        sentidoOrder = SortOrder.Descending;
                    else
                        sentidoOrder = SortOrder.Ascending;
                }
                else
                    columOrder = column;

                lista.Sorting = sentidoOrder;
                SortListView(lista, column, tipoColuna);
            }
            catch (Exception ex)
            {
                HandleException("Ordenar Lista", ex);
            }
        }
        private void SortListView(ListView lista, int column, OrdenacaoListView.Tipo tipo)
        {
            switch (tipo)
            {
                case OrdenacaoListView.Tipo.Alfabetica:
                    switch (lista.Sorting)
                    {
                        case SortOrder.Ascending:
                            lista.ListViewItemSorter = new OrdenacaoListView(column, OrdenacaoListView.Tipo.Alfabetica, OrdenacaoListView.Direcao.Ascendente);
                            break;
                        case SortOrder.Descending:
                            lista.ListViewItemSorter = new OrdenacaoListView(column, OrdenacaoListView.Tipo.Alfabetica, OrdenacaoListView.Direcao.Descendente);
                            break;
                        case SortOrder.None:
                            lista.ListViewItemSorter = new OrdenacaoListView(column, OrdenacaoListView.Tipo.Alfabetica, OrdenacaoListView.Direcao.Ascendente);
                            break;
                    }
                    break;
                case OrdenacaoListView.Tipo.Numerica:
                    switch (lista.Sorting)
                    {
                        case SortOrder.Ascending:
                            lista.ListViewItemSorter = new OrdenacaoListView(column, OrdenacaoListView.Tipo.Numerica, OrdenacaoListView.Direcao.Ascendente);
                            break;
                        case SortOrder.Descending:
                            lista.ListViewItemSorter = new OrdenacaoListView(column, OrdenacaoListView.Tipo.Numerica, OrdenacaoListView.Direcao.Descendente);
                            break;
                        case SortOrder.None:
                            lista.ListViewItemSorter = new OrdenacaoListView(column, OrdenacaoListView.Tipo.Numerica, OrdenacaoListView.Direcao.Ascendente);
                            break;
                    }
                    break;
                case OrdenacaoListView.Tipo.Decimal:
                    switch (lista.Sorting)
                    {
                        case SortOrder.Ascending:
                            lista.ListViewItemSorter = new OrdenacaoListView(column, OrdenacaoListView.Tipo.Decimal, OrdenacaoListView.Direcao.Ascendente);
                            break;
                        case SortOrder.Descending:
                            lista.ListViewItemSorter = new OrdenacaoListView(column, OrdenacaoListView.Tipo.Decimal, OrdenacaoListView.Direcao.Descendente);
                            break;
                        case SortOrder.None:
                            lista.ListViewItemSorter = new OrdenacaoListView(column, OrdenacaoListView.Tipo.Decimal, OrdenacaoListView.Direcao.Ascendente);
                            break;
                    }
                    break;
                case OrdenacaoListView.Tipo.Data:
                    switch (lista.Sorting)
                    {
                        case SortOrder.Ascending:
                            lista.ListViewItemSorter = new OrdenacaoListView(column, OrdenacaoListView.Tipo.Data, OrdenacaoListView.Direcao.Ascendente);
                            break;
                        case SortOrder.Descending:
                            lista.ListViewItemSorter = new OrdenacaoListView(column, OrdenacaoListView.Tipo.Data, OrdenacaoListView.Direcao.Descendente);
                            break;
                        case SortOrder.None:
                            lista.ListViewItemSorter = new OrdenacaoListView(column, OrdenacaoListView.Tipo.Data, OrdenacaoListView.Direcao.Ascendente);
                            break;
                    }
                    break;
            }
            lista.Sort();
        }
        private FrmMain GetMainForm()
        {
            return Program.GetForm<FrmMain>();
        }
        protected void SaveListColumnState(ListView list)
        {
            BusinessEntity.Configuration.ListConfiguration listConfig = Program.SystemConfiguration.ListStateConfiguration.Find(it => it.ControlName.CompareTo(list.Name) == 0);
            if (listConfig == null)
            {
                listConfig = new GTA.BusinessEntity.Configuration.ListConfiguration();
                listConfig.ControlName = list.Name;
                listConfig.Columns = GetListColumnsState(list);
                Program.SystemConfiguration.ListStateConfiguration.Add(listConfig);
            }
            else
                listConfig.Columns = GetListColumnsState(list);

            Program.SaveSystemConfiguration();
        }
        private List<BusinessEntity.Configuration.ListConfiguration.ListColumn> GetListColumnsState(ListView list)
        {
            List<BusinessEntity.Configuration.ListConfiguration.ListColumn> result = new List<GTA.BusinessEntity.Configuration.ListConfiguration.ListColumn>();
            foreach (ColumnHeader itemColumn in list.Columns)
            {
                result.Add(new GTA.BusinessEntity.Configuration.ListConfiguration.ListColumn
                {
                    DisplayIndex = itemColumn.DisplayIndex,
                    ImageIndex = itemColumn.ImageIndex,
                    Index = itemColumn.Index,
                    Text = itemColumn.Text,
                    TextAlign = (int)itemColumn.TextAlign,
                    Width = itemColumn.Width
                });
            }
            return result;
        }
        protected void RestoreListColumnState(ListView list)
        {
            BusinessEntity.Configuration.ListConfiguration listConfig = Program.SystemConfiguration.ListStateConfiguration.Find(it => it.ControlName.CompareTo(list.Name) == 0);
            if (listConfig != null)
            {
                if (listConfig.Columns != null && listConfig.Columns.Count > 0)
                {
                    foreach (BusinessEntity.Configuration.ListConfiguration.ListColumn itemColumn in listConfig.Columns)
                    {
                        list.Columns[itemColumn.Index].DisplayIndex = itemColumn.DisplayIndex;
                        list.Columns[itemColumn.Index].ImageIndex = itemColumn.ImageIndex;
                        list.Columns[itemColumn.Index].Text = itemColumn.Text;
                        list.Columns[itemColumn.Index].TextAlign = (HorizontalAlignment)itemColumn.TextAlign;
                        list.Columns[itemColumn.Index].Width = itemColumn.Width;
                    }
                }
            }
        }
        #endregion
    }

    public class OrdenacaoListView : IComparer
    {
        #region Enum
        public enum Tipo
        {
            Alfabetica,
            Numerica,
            Decimal,
            Data
        }
        public enum Direcao
        {
            Ascendente,
            Descendente
        }
        #endregion

        #region Atributos
        private int coluna = 0;
        private Tipo tipoOrdem = Tipo.Alfabetica;
        private Direcao direcaoLista = Direcao.Ascendente;
        #endregion

        #region Propriedade
        public Direcao DirecaoLista
        {
            get { return direcaoLista; }
            set { direcaoLista = value; }
        }
        public int Coluna
        {
            get { return coluna; }
            set { coluna = value; }
        }
        public Tipo TipoOrdem
        {
            get { return tipoOrdem; }
            set { tipoOrdem = value; }
        }
        #endregion

        #region Construtores
        public OrdenacaoListView(int colunaItem, Tipo tipoOrdenacao, Direcao direcaoParam)
        {
            coluna = (colunaItem != int.MinValue) ? colunaItem : 0;
            tipoOrdem = tipoOrdenacao;
            direcaoLista = direcaoParam;
        }
        public OrdenacaoListView(int colunaItem, Tipo tipoOrdenacao)
        {
            coluna = (colunaItem != int.MinValue) ? colunaItem : 0;
            tipoOrdem = tipoOrdenacao;
        }
        public OrdenacaoListView(int colunaItem)
        {
            coluna = (colunaItem != int.MinValue) ? colunaItem : 0;
        }
        public OrdenacaoListView()
        {
        }
        #endregion

        #region IComparer Members
        public int Compare(object x, object y)
        {
            int resultado = 0;

            ListViewItem item1 = (ListViewItem)x;
            ListViewItem item2 = (ListViewItem)y;

            if (!String.IsNullOrEmpty(item1.SubItems[coluna].Text.Trim()) && !String.IsNullOrEmpty(item2.SubItems[coluna].Text.Trim()))
            {
                switch (tipoOrdem)
                {
                    case Tipo.Alfabetica:
                        switch (direcaoLista)
                        {
                            case Direcao.Ascendente:
                                resultado = item1.SubItems[coluna].Text.CompareTo(item2.SubItems[coluna].Text);
                                break;
                            case Direcao.Descendente:
                                resultado = item2.SubItems[coluna].Text.CompareTo(item1.SubItems[coluna].Text);
                                break;
                        }
                        break;
                    case Tipo.Numerica:
                        switch (direcaoLista)
                        {
                            case Direcao.Ascendente:
                                resultado = Convert.ToInt32(item1.SubItems[coluna].Text, CultureInfo.CurrentCulture).CompareTo(Convert.ToInt32(item2.SubItems[coluna].Text));
                                break;
                            case Direcao.Descendente:
                                resultado = Convert.ToInt32(item2.SubItems[coluna].Text, CultureInfo.CurrentCulture).CompareTo(Convert.ToInt32(item1.SubItems[coluna].Text));
                                break;
                        }
                        break;
                    case Tipo.Decimal:
                        switch (direcaoLista)
                        {
                            case Direcao.Ascendente:
                                resultado = Convert.ToDecimal(item1.SubItems[coluna].Text).CompareTo(Convert.ToDecimal(item2.SubItems[coluna].Text));
                                break;
                            case Direcao.Descendente:
                                resultado = Convert.ToDecimal(item2.SubItems[coluna].Text).CompareTo(Convert.ToDecimal(item1.SubItems[coluna].Text));
                                break;
                        }
                        break;
                    case Tipo.Data:
                        switch (direcaoLista)
                        {
                            case Direcao.Ascendente:
                                resultado = Convert.ToDateTime(item1.SubItems[coluna].Text.Replace("-", "")).CompareTo(Convert.ToDateTime(item2.SubItems[coluna].Text.Replace("-", "")));
                                break;
                            case Direcao.Descendente:
                                resultado = Convert.ToDateTime(item2.SubItems[coluna].Text.Replace("-", "")).CompareTo(Convert.ToDateTime(item1.SubItems[coluna].Text.Replace("-", "")));
                                break;
                        }
                        break;
                }
            }
            else
            {
                switch (direcaoLista)
                {
                    case Direcao.Ascendente:
                        if (String.IsNullOrEmpty(item1.SubItems[coluna].Text.Trim()) && !String.IsNullOrEmpty(item2.SubItems[coluna].Text.Trim()))
                            resultado = -1;
                        else if (!String.IsNullOrEmpty(item1.SubItems[coluna].Text.Trim()) && String.IsNullOrEmpty(item2.SubItems[coluna].Text.Trim()))
                            resultado = 1;
                        break;
                    case Direcao.Descendente:
                        if (String.IsNullOrEmpty(item2.SubItems[coluna].Text.Trim()) && !String.IsNullOrEmpty(item1.SubItems[coluna].Text.Trim()))
                            resultado = -1;
                        else if (!String.IsNullOrEmpty(item2.SubItems[coluna].Text.Trim()) && String.IsNullOrEmpty(item1.SubItems[coluna].Text.Trim()))
                            resultado = 1;
                        break;
                }
            }

            return resultado;
        }
        #endregion
    }
}